package cn.geminis.workflow.client;

import cn.geminis.auth.context.LoginUserRequestInterceptor;
import cn.geminis.data.jpa.PageQuery;
import cn.geminis.workflow.client.filter.TaskFilter;
import lombok.SneakyThrows;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Allen
 */
@FeignClient(value = "workflow",
        path = "/",
        configuration = LoginUserRequestInterceptor.class,
        primary = false)
public interface WorkflowClient {

    /**
     * 启动流程
     *
     * @param key         流程key
     * @param businessKey 业务编号
     * @return 业务编号
     */
    @PostMapping(path = "/process/{key}/start/{businessKey}")
    String processStart(
            @PathVariable(name = "key") String key,
            @PathVariable(name = "businessKey", required = false) String businessKey,
            @RequestBody Object value
    );

    @DeleteMapping(path = "/process/stop/{processKey}/{businessKey}")
    void processStop(
            @PathVariable(name = "processKey") String processKey,
            @PathVariable(name = "businessKey") String businessKey
    );

    /**
     * 指定用户
     *
     * @param businessKey 业务编号
     */
    @PutMapping(path = "/task/{businessKey}/assignee/{instanceId}")
    void taskAssignee(
            @PathVariable(name = "businessKey") String businessKey,
            @PathVariable(name = "instanceId", required = false) String instanceId
    );

    /**
     * 获取功能
     *
     * @param approve 完成参数
     */
    @PutMapping(path = "/task/complete")
    void taskComplete(
            @RequestBody Approve approve
    );

    @GetMapping("/history/process")
    Page<Process> processes(@SpringQueryMap PageQuery pageParameter);

    @GetMapping("/history/task")
    Page<Task> tasks(@RequestParam Map<String, Object> map);

    default Page<Task> tasks(PageQuery pageParameter, TaskFilter queryParameter) {
        var pageMap = getObjectToMap(pageParameter);
        var filterMap = getObjectToMap(queryParameter);
        pageMap.putAll(filterMap);

        return tasks(pageMap);
    }

    @GetMapping("/data/{taskInstanceId}")
    Map<String, Object> taskData(@PathVariable("taskInstanceId") String taskInstanceId);


    @SneakyThrows
    private static Map<String, Object> getObjectToMap(Object obj) {
        var map = new HashMap<String, Object>();
        if (obj != null) {
            var cla = obj.getClass();
            var fields = cla.getDeclaredFields();
            for (var field : fields) {
                field.setAccessible(true);
                var keyName = field.getName();
                var value = field.get(obj);
                if (value != null) {
                    map.put(keyName, value);
                }
            }
        }
        return map;
    }
}
